{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from sklearn import tree\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "seed = 1024\n",
    "np.random.seed(seed)\n",
    "\n",
    "path = '../data/'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "train_x = pd.read_pickle(path + 'train_X.pkl')\n",
    "valid_x = pd.read_pickle(path + 'valid_X.pkl')\n",
    "dev_x = pd.read_pickle(path + 'dev_X.pkl')\n",
    "\n",
    "y_train = pd.read_pickle(path+'train.pkl')['label'].values\n",
    "y_valid = pd.read_pickle(path+'valid.pkl')['label'].values\n",
    "y_dev = pd.read_pickle(path+'dev.pkl')['label'].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "s_train = pd.read_pickle(path+'train.pkl')\n",
    "a_valid = pd.read_pickle(path+'valid.pkl')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def tradaboost(trans_S, trans_A, label_S, label_A, test, N):\n",
    "    trans_data = np.concatenate((trans_A, trans_S), axis=0)\n",
    "    trans_label = np.concatenate((label_A, label_S), axis=0)\n",
    "\n",
    "    row_A = trans_A.shape[0]\n",
    "    row_S = trans_S.shape[0]\n",
    "    row_T = test.shape[0]\n",
    "\n",
    "    test_data = np.concatenate((trans_data, test), axis=0)\n",
    "\n",
    "    # 初始化权重\n",
    "    weights_A = np.ones([row_A, 1]) / row_A\n",
    "    weights_S = np.ones([row_S, 1]) / row_S\n",
    "    weights = np.concatenate((weights_A, weights_S), axis=0)\n",
    "\n",
    "    bata = 1 / (1 + np.sqrt(2 * np.log(row_A / N)))\n",
    "\n",
    "    bata_T = np.zeros([1, N])\n",
    "    result_label = np.ones([row_A + row_S + row_T, N])\n",
    "\n",
    "    predict = np.zeros([row_T])\n",
    "\n",
    "    print('params initial finished.')\n",
    "    trans_data = np.asarray(trans_data, order='C')\n",
    "    trans_label = np.asarray(trans_label, order='C')\n",
    "    test_data = np.asarray(test_data, order='C')\n",
    "\n",
    "    for i in range(N):\n",
    "        P = calculate_P(weights, trans_label)\n",
    "\n",
    "        result_label[:, i] = train_classify(trans_data, trans_label,\n",
    "                                            test_data, P)\n",
    "        print('result,', result_label[:, i], row_A, row_S, i, result_label.shape)\n",
    "\n",
    "        error_rate = calculate_error_rate(label_S, result_label[row_A:row_A + row_S, i],\n",
    "                                          weights[row_A:row_A + row_S, :])\n",
    "        print('Error rate:', error_rate)\n",
    "        if error_rate > 0.5:\n",
    "            error_rate = 0.5\n",
    "        if error_rate == 0:\n",
    "            N = i\n",
    "            break  # 防止过拟合\n",
    "            # error_rate = 0.001\n",
    "\n",
    "        bata_T[0, i] = error_rate / (1 - error_rate)\n",
    "\n",
    "        # 调整源域样本权重\n",
    "        for j in range(row_S):\n",
    "            weights[row_A + j] = weights[row_A + j] * np.power(bata_T[0, i],\n",
    "                                                               np.abs(result_label[row_A + j, i] - label_S[j]))\n",
    "\n",
    "        # 调整辅域样本权重\n",
    "        for j in range(row_A):\n",
    "            weights[j] = weights[j] * np.power(bata, (-np.abs(result_label[j, i] - label_A[j])))\n",
    "    # print bata_T\n",
    "    for i in range(row_T):\n",
    "        # 跳过训练数据的标签\n",
    "        left = np.sum(\n",
    "            result_label[row_A + row_S + i, int(np.ceil(N / 2)):N] * np.log(1 / bata_T[0, int(np.ceil(N / 2)):N]))\n",
    "        right = 0.5 * np.sum(np.log(1 / bata_T[0, int(np.ceil(N / 2)):N]))\n",
    "\n",
    "        if left >= right:\n",
    "            predict[i] = 1\n",
    "        else:\n",
    "            predict[i] = 0\n",
    "            # print left, right, predict[i]\n",
    "\n",
    "    return predict\n",
    "\n",
    "\n",
    "def calculate_P(weights, label):\n",
    "    total = np.sum(weights)\n",
    "    return np.asarray(weights / total, order='C')\n",
    "\n",
    "\n",
    "def train_classify(trans_data, trans_label, test_data, P):\n",
    "    clf = tree.DecisionTreeClassifier(criterion=\"gini\", max_features=\"log2\", splitter=\"random\")\n",
    "    clf.fit(trans_data, trans_label, sample_weight=P[:, 0])\n",
    "    return clf.predict(test_data)\n",
    "\n",
    "\n",
    "def calculate_error_rate(label_R, label_H, weight):\n",
    "    total = np.sum(weight)\n",
    "\n",
    "    print(weight[:, 0] / total)\n",
    "    print(np.abs(label_R - label_H))\n",
    "    return np.sum(weight[:, 0] / total * np.abs(label_R - label_H))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "#need tradaboost方法\n",
    "s_train = s_train.reset_index(drop=1)\n",
    "s_ind = s_train[s_train.field=='movie'].index\n",
    "a_ind = s_train[s_train.field=='hotel'].index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "a_valid = a_valid.reset_index()\n",
    "a2_valid = a_valid[a_valid.field=='movie'].index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "params initial finished.\n",
      "result, [ 1.  1.  0. ...,  0.  1.  1.] 3144 21592 0 (27444, 1)\n",
      "[  4.63134494e-05   4.63134494e-05   4.63134494e-05 ...,   4.63134494e-05\n",
      "   4.63134494e-05   4.63134494e-05]\n",
      "[ 0.  0.  0. ...,  0.  0.  0.]\n",
      "Error rate: 0.0\n"
     ]
    }
   ],
   "source": [
    "ret = tradaboost(train_x[s_ind.values],train_x[a_ind.values],y_train[s_ind.values],y_train[a_ind.values],valid_x[a2_valid.values],1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 1.,  1.,  1., ...,  1.,  1.,  1.])"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ensembel model  the accuracy on the dev set is : 61.09%\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "ret = train_classify(train_x,y_train,valid_x)\n",
    "y_t = (ret+0.5).astype(int)\n",
    "acc =  accuracy_score(y_valid,y_t)\n",
    "\n",
    "print('ensembel model  the accuracy on the dev set is : {}%'.format(round(acc* 100,2)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
